package cn.rxmind.dlicense.core.base;

import cn.rxmind.dlicense.core.validator.DLicenseValidator;
import cn.rxmind.dlicense.core.validator.WhenInstallValidator;
import de.schlichtherle.license.*;
import de.schlichtherle.xml.GenericCertificate;
import lombok.Getter;

/**
 * 证书管理器扩展
 *
 * @author renxin
 * @email renxinzhiliangzhi@163.com
 * @date 2021/4/13 10:41 上午
 */
public class LicenseManagerWrapper extends LicenseManager {

    private final DLicenseValidator validatorWhenInstall ;

    @Getter
    private DLicenseContent installedDLicenseContent;

    private boolean installed;

    private final LicenseBytesReader licenseBytesReader;

    public LicenseManagerWrapper(LicenseParam licenseParam,
                                 LicenseBytesReader licenseBytesReader) {
        super(licenseParam);
        this.licenseBytesReader = licenseBytesReader;
        this.validatorWhenInstall = new WhenInstallValidator();
    }

    /**
     * 原有verify方法证书内容加载30分钟内不再校验，这里新增实时的verify方法
     * <p>
     * {@link LicenseManager#verify(de.schlichtherle.license.LicenseNotary)}
     *
     * @throws Exception
     */
    private synchronized void cachelessVerify() throws Exception{

        LicenseNotary notary = getLicenseNotary();

        // Load license key from preferences,
        final byte[] key = getLicenseKey();
        if (null == key) {
            throw new NoLicenseInstalledException(getLicenseParam().getSubject());
        }
        GenericCertificate certificate = getPrivacyGuard().key2cert(key);
        notary.verify(certificate);
        final LicenseContent content = (LicenseContent) certificate.getContent();
        validate(content);
        setCertificate(certificate);

    }

    /**
     * 证书安装
     * @throws Exception
     */
    public synchronized DLicenseContent install() throws Exception {
        if(!installed) {
            byte[] bytes = null;
            try {
                bytes = licenseBytesReader.get();
            }catch (Exception e){
                System.err.printf("证书读取发生错误！%s%n",e.getMessage());
                System.exit(-1);
            }
            LicenseContent licenseContent = install(bytes, getLicenseNotary());
            // 安装完成时检验证书合法性,此后便不再检验
            cachelessVerify();
            installed = true;
            this.installedDLicenseContent = (DLicenseContent) licenseContent.getExtra();
        }
        return this.installedDLicenseContent;
    }

    /**
     * 重写父类 validate 方法，将证书生效时间异常输出
     * @param content
     * @throws LicenseContentException
     */
    @Override
    protected synchronized void validate(LicenseContent content) throws LicenseContentException {
        DLicenseContent dLicenseContent = (DLicenseContent)content.getExtra();
        this.validatorWhenInstall.validateLicense(dLicenseContent);
        super.validate(content);
    }



}
